package com.demo.connectdbtest.module.gitlab.controller;

import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.JschConfigSessionFactory;
import org.eclipse.jgit.transport.OpenSshConfig;
import org.eclipse.jgit.transport.SshSessionFactory;
import org.eclipse.jgit.transport.SshTransport;
import org.eclipse.jgit.util.FS;
import org.gitlab4j.api.GitLabApi;
import org.gitlab4j.api.GitLabApiException;
import org.gitlab4j.api.models.Project;
import org.gitlab4j.api.models.TreeItem;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/gitlab")
@Slf4j
public class GitlabController {

    //accessToken的获取：http://t.csdn.cn/wh45Q

    @RequestMapping("/clone")
    public String fileClone() {
        try {
            GitLabApi connect = GitLabApi.oauth2Login("http://192.168.159.129:80", "root", "1316jicai");
            List<Project> projects = connect.getProjectApi().getProjects();
            return projects + "";
            /* GitlabAPI connect = GitlabAPI.connect("http://192.168.159.129:80", "glpat-TGZUk6NqYK2P53fR1G7x");
        //条件获取project
        //nameSpace 项目的命令空间
        //projectName 项目名称
        GitlabProject project = null;
        try {
            project = connect.getProject("Administrator", "test_template");
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("获取连接对象");
        System.out.println(project);
        List<GitlabBranch> branches = connect.getBranches(project);
        return branches.toString();*/
//            List<Project> projects = null;
            //  projects = new GitLabApiUtil().getProjects();
//            System.out.println(projects);

        } catch (GitLabApiException e) {
            e.printStackTrace();
            System.out.println(e);
            return "error";
        }

    }


    @RequestMapping("/list")
    public String listProject() throws GitLabApiException {
        GitLabApi gitLabApi = new GitLabApi("http://192.168.159.129:80", "glpat-NzJcToDfEBy49fdv9-QL");
        List<Project> projects = gitLabApi.getProjectApi().getProjects();
        for (Project project : projects) {
            System.out.println("获取的项目");
            System.out.println(project);
        }
        List<Project> test_template = projects.stream().filter(item -> item.getName().equals("test_template")).collect(Collectors.toList());
        Project project = test_template.get(0);

        // 获取工程的所有文件
        List<String> allFil = getAllFiles(project.getId(), "D:\\data\\test_template", "master", gitLabApi);

        // 遍历获取所有文件，进行相关的处理
        allFil.forEach(filePath -> {
            try {
                // 读取文件内容
                InputStream inputStream = gitLabApi.getRepositoryFileApi().getRawFile(project.getId(), "master", filePath);
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                StringBuilder stringBuilder = new StringBuilder();
                while (reader.ready()) {
                    String lineContent = reader.readLine();
                    stringBuilder.append(lineContent);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            // todo 进行相关的处理
        });
        return "ok";
    }

    //读取工程仓库的所有文件列表
    private List<String> getAllFiles(Integer projectId, String directory, String branch, GitLabApi gitLabApi) {
        List<String> fileNames = new ArrayList<>();
        try {
            gitLabApi.getRepositoryApi().getTree(projectId, directory, branch).forEach(file -> {
                // 如果当前是目录，则继续获取其下的文件列表
                if (file.getType().equals(TreeItem.Type.TREE)) {
                    fileNames.addAll(getAllFiles(projectId, file.getPath(), branch, gitLabApi));
                    return;
                }
                // 如果是文件类型，直接添加
                final String filePath = String.join("/", directory, file.getName());
                fileNames.add(filePath);
            });
        } catch (GitLabApiException e) {
            e.printStackTrace();
        }
        return fileNames;
    }


    //原文链接：https://blog.csdn.net/github_35735591/article/details/124230774

    @RequestMapping("/ssh/clone")
    public void sshRepositoryClone() {
        String localCodeDir = "C:\\Users\\Administrator\\Desktop\\practice\\demo"; //本地文件夹
        String remoteRepoPath = "ssh://git@10.252.171.20:21022/SQD/testproject.git"; //git地址
        String keyPath = "C:\\Users\\Administrator\\.ssh\\id_rsa";  //私钥文件
        gitClone(remoteRepoPath, localCodeDir, keyPath);

    }


    //localRepoPath 为本地文件夹
    //keyPath 私钥文件 path
    //remoteRepoPath 为 ssh git远端仓库地址
    protected static void gitClone(String remoteRepoPath, String localRepoPath, String keyPath) {
        //ssh session的工厂,用来创建密匙连接
        SshSessionFactory sshSessionFactory = new JschConfigSessionFactory() {
            @Override
            protected void configure(OpenSshConfig.Host host, Session session) {
                session.setConfig("StrictHostKeyChecking", "no");
            }

            @Override
            protected JSch createDefaultJSch(FS fs) throws JSchException {
                JSch sch = super.createDefaultJSch(fs);
                sch.addIdentity(keyPath); //添加私钥文件
                return sch;
            }
        };

        //克隆代码库命令
        CloneCommand cloneCommand = Git.cloneRepository();
        Git git = null;
        try {
            git = cloneCommand.setURI(remoteRepoPath) //设置远程URI
                    .setTransportConfigCallback(transport -> {
                        SshTransport sshTransport = (SshTransport) transport;
                        sshTransport.setSshSessionFactory(sshSessionFactory);
                    })
                    .setDirectory(new File(localRepoPath)) //设置下载存放路径
                    .call();
            System.out.println("success");
        } catch (Exception e) {
            System.out.println("fail");
            e.printStackTrace();
        } finally {
            if (git != null) {
                git.close();
            }
        }
    }


    @RequestMapping("/ssh/clone/test")
    public String testSshRepositoryClone() {
        //克隆git项目
        String commitId = "25bf984";
        String repositoryPath = "/data/project/javaProject/qualityManage/repository/GIT/217V3.1.6.120";
        String codeUrl = "ssh://git@10.252.171.20:21022/SQD/testproject.git";
        String repositoryName = " 217V3.1.6.120";
        String repositoryDir = "/data/project/javaProject/qualityManage/repository/GIT";
        StringBuilder executeCmd = new StringBuilder();
        if (File.separator.equals("\\")) {
            executeCmd.append("cmd /c cd " + repositoryDir + " && git clone " + codeUrl + " " + repositoryName + " && cd " + repositoryPath + " && git checkout " + commitId);
        } else {
            executeCmd.append("cd " + repositoryDir + " ; git clone " + codeUrl + " " + repositoryName + " ; cd " + repositoryPath + " ; git checkout " + commitId);
        }
        try {
            log.debug("克隆命令：" + executeCmd);
            Thread thread = new Thread(() -> {
                log.info("执行thread线程任务");
                Process result = null;
                try {
                    result = Runtime.getRuntime().exec(String.valueOf(executeCmd));
                    log.info("已执行克隆仓库的命令");
                } catch (IOException e) {
                    e.printStackTrace();
                }
                InputStream inputStream = result.getInputStream();
                InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
                String strInput;
                while (true) {
                    try {
                        if (!StringUtils.isEmpty(strInput = bufferedReader.readLine())) {
                            log.info("克隆操作的输出信息：{}", strInput);
                        } else {
                            break;
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });
            thread.start();
            File file = new File(repositoryPath);
            if (file.exists() && file.isDirectory()) {
                System.out.println("目录存在");
            } else {
                System.out.println("未克隆到指定git仓库");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "ERROR";
        }
        return "SUCCESS";
    }


}
